//========== 调试开关配置 ==========
const DEBUG_ENABLED = false; // 主开关：true=开启所有打印，false=关闭所有打印

// 条件打印函数
function debugLog(...args) {
  if (DEBUG_ENABLED) {
    console.log(...args);
  }
}

//========== 原有代码开始 ==========
//如果代理函数的时候，打印了函数的所有内容了，证明没有保护该函数
ffglobal = {};
//描述符检测，函数toString检测
!(() => {
  "use strict";
  const $toString = Function.toString; //hook Function.toString 且命名为myToString
  //变量名取随机数防检测
  const myFunction_toString_symbol = Symbol(
    "(".concat("", ")_", (Math.random() + "").toString(36))
  );
  const myToString = function () {
    return (
      (typeof this == "function" && this[myFunction_toString_symbol]) ||
      $toString.call(this)
    ); //谁调用这个方法,this就是谁,比如boda调用,这个this就是boda
  };

  function set_native(func, key, value) {
    //定义描述符
    Object.defineProperty(func, key, {
      enumerable: false,
      configurable: true,
      writable: true,
      value: value,
    });
  }
  delete Function.prototype["toString"]; //删除原型链上的toString
  set_native(Function.prototype, "toString", myToString); //自己定义个getter方法
  //myToString的 myFunction_toString_symbol属性设置为  function toString() { [native code] }
  //myFunction_toString_symbol= function toString() { [native code] }
  set_native(
    Function.prototype.toString,
    myFunction_toString_symbol,
    "function toString() { [native code] }"
  ); //套个娃 保护一下我们定义的toString 否则就暴露了
  ffglobal.safefunction = (func, name) => {
    set_native(
      func,
      myFunction_toString_symbol,
      `function ${(myFunction_toString_symbol, name || "")}() { [native code] }`
    );
    set_native(func, "name", `${(myFunction_toString_symbol, name || "")}`);
    // }
  }; //导出函数到globalThis
}).call(this);
//对象标识符检测
ffglobal.reNameObj = function reNameObj(obj, obname) {
  Object.defineProperty(obj.prototype, Symbol.toStringTag, {
    value: obname,
    configurable: true,
    writable: false,
    enumerable: false,
  });
};

/////============================
window = top = self = parent = globalThis;
process_ = process;
delete global;
delete __dirname;
delete __filename;
delete process;
delete module;
// delete require;
delete exports;
XMLHttpRequest = function XMLHttpRequest() {
  debugger;
};
ffglobal.safefunction(XMLHttpRequest, "XMLHttpRequest");
XMLHttpRequest.prototype.send = function send() {
  debugger;
};
ffglobal.safefunction(
  XMLHttpRequest.prototype.send,
  "XMLHttpRequest.prototype.send"
);
window.requestAnimationFrame = function requestAnimationFrame() {
  debugger;
};
ffglobal.safefunction(window.requestAnimationFrame, "requestAnimationFrame");
window._sdkGlueVersionMap = {
  sdkGlueVersion: "1.0.0.64-fix.01",
  bdmsVersion: "1.0.1.19-fix.01",
  captchaVersion: "4.0.10",
};
window.EventSource = function () {};
ffglobal.safefunction(window.EventSource, "EventSource");
window.addEventListener = function () {};
ffglobal.safefunction(window.addEventListener, "addEventListener");
window.CanvasRenderingContext2D = function () {};
ffglobal.safefunction(
  window.CanvasRenderingContext2D,
  "CanvasRenderingContext2D"
);
window.Audio = function () {};
ffglobal.safefunction(window.Audio, "Audio");
setTimeout = function setTimeout() {};
ffglobal.safefunction(setTimeout, "setTimeout");
setInterval = function setInterval() {};
ffglobal.safefunction(setInterval, "setInterval");
window.outerWidth = 1440;
window.outerHeight = 778;
window.innerWidth = 1440;
window.innerHeight = 778;
document = {};
HTMLAllCollection = function HTMLAllCollection() {};
ffglobal.safefunction(HTMLAllCollection, "HTMLAllCollection");
Object.defineProperty(HTMLAllCollection, Symbol.toStringTag, {
  value: "HTMLAllCollection",
});
_all = {
  [Symbol.toStringTag]: "HTMLAllCollection",
};
document.all = _all;
document.all.__proto__ = HTMLAllCollection.prototype;
ffglobal.safefunction(document.all, "_all");
debugLog("document.all.toString()==>", document.all.toString());
debugLog(
  "document.all[Symbol.toStringTag]==>",
  document.all[Symbol.toStringTag]
);

_documentElement = {
  [Symbol.toStringTag]: "HTMLHtmlElement",
};
document.documentElement = _documentElement;
ffglobal.safefunction(document.documentElement, "_documentElement");
debugLog(
  "document.documentElement.toString()==>",
  document.documentElement.toString()
);
debugLog(
  "document.documentElement[Symbol.toStringTag]==>",
  document.documentElement[Symbol.toStringTag]
);

DOMTokenList = function DOMTokenList() {};
ffglobal.safefunction(DOMTokenList, "DOMTokenList");
Object.defineProperties(DOMTokenList, {
  length: {
    value: 0,
    writable: false,
    enumerable: false,
    configurable: true,
  },
  name: {
    value: "DOMTokenList",
    writable: false,
    enumerable: false,
    configurable: true,
  },
});
Object.defineProperties(DOMTokenList.prototype, {
  entries: {
    value: function entries() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  keys: {
    value: function keys() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  values: {
    value: function values() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  forEach: {
    value: function forEach() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  add: {
    value: function add() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  contains: {
    value: function contains() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  item: {
    value: function item() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  remove: {
    value: function remove() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  replace: {
    value: function replace() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  supports: {
    value: function supports() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
  toggle: {
    value: function toggle() {},
    enumerable: true,
    configurable: true,
    writable: true,
  },
});
Object.defineProperty(DOMTokenList.prototype, Symbol.toStringTag, {
  value: "DOMTokenList",
});
_span = {
  classList: new DOMTokenList(),
  [Symbol.toStringTag]: "HTMLSpanElement",
};
ffglobal.safefunction(_span, "_span");

_canvas = {
  toDataURL: function toDataURL() {
    return "";
  },
};
ffglobal.safefunction(_canvas, "_canvas");
document.createElement = function createElement(arg) {
  debugLog("document中的createElement的参数为==>", arg);
  if (arg.toLowerCase() == "span") return _span;
  if (arg.toLowerCase() == "canvas") return _canvas;
  debugger;
};
ffglobal.safefunction(document.createElement, "createElement");

document.createEvent = function createEvent(arg) {
  debugLog("document中的createEvent的参数为==>", arg);
  debugger;
};
ffglobal.safefunction(document.createEvent, "createEvent");
document.addEventListener = function addEventListener(arg) {
  debugLog("document中的addEventListener的参数为==>", arg);
  debugger;
};
ffglobal.safefunction(document.addEventListener, "addEventListener");

location = {
  ancestorOrigins: {},
  href: "https://www.douyin.com/?recommend=1",
  origin: "https://www.douyin.com",
  protocol: "https:",
  host: "www.douyin.com",
  hostname: "www.douyin.com",
  port: "",
  pathname: "/",
  search: "?recommend=1",
  hash: "",
};
navigator = {
  appCodeName: "Mozilla",
  appName: "Netscape",
  appVersion:
    "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
  cookieEnabled: true,
  doNotTrack: null,
  hardwareConcurrency: 12,
  language: "zh-CN",
  languages: ["zh-CN", "zh"],
  maxTouchPoints: 0,
  onLine: true,
  pdfViewerEnabled: true,
  platform: "Win32",
  plugins: {
    length: 4,
    [Symbol.toStringTag]: "PluginArray",
    0: {
      name: "PDF Viewer",
      [Symbol.toStringTag]: "Plugin",
      length: 2,
    },
    1: {
      name: "ff_ss",
      [Symbol.toStringTag]: "Plugin",
      length: 2,
    },
    2: {
      name: "ss_ff",
      [Symbol.toStringTag]: "Plugin",
      length: 2,
    },
    3: {
      name: "FFloveSS",
      [Symbol.toStringTag]: "Plugin",
      length: 2,
    },
  },
  product: "Gecko",
  productSub: "20030107",
  userAgent:
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
  vendor: "Google Inc.",
  vendorSub: "",
  webdriver: false,
  storage: {
    [Symbol.toStringTag]: "StorageManager",
  },
  connection: {
    downlink: 10,
    downlinkMax: 10,
    effectiveType: "4g",
    rtt: 50,
    onchange: function () {},
    saveData: false,
  },
  userAgentData: {
    brands: [
      {
        brand: "Not)A;Brand",
        version: "8",
      },
      {
        brand: "Chromium",
        version: "138",
      },
      {
        brand: "Microsoft Edge",
        version: "138",
      },
    ],
    mobile: false,
    platform: "Windows",
  },
};

history = {};
screen = {
  availHeight: 901,
  availLeft: 0,
  availTop: 0,
  availWidth: 1412,
  colorDepth: 24,
  height: 1080,
  pixelDepth: 24,
  width: 1920,
};
localStorage = {
  xmst: "eCky5NPwTP8egExt-kFJgudpia2f7jFU_tSZCSXaRkh-z0lLonzYERc-0r5XyEBNpVTPfagUkavInLiq7TPsh7Ru7vJq26B6lHtu3U0F6eI85FubSVFlE_AfJX1SzxF1Wn0o0-AiEaBrrAV7WG9WTHYGlNkEVV59D97JZY45YASY5KEtQEHPqg==",
};
localStorage.getItem = function getItem(key) {
  debugLog("localStorage中的getItem的参数为==>", key);
  return localStorage[key];
};
ffglobal.safefunction(localStorage.getItem, "getItem");
sessionStorage = {};
sessionStorage.getItem = function getItem(key) {
  debugLog("sessionStorage中的getItem的参数为==>", key);
  return sessionStorage[key];
};
ffglobal.safefunction(sessionStorage.getItem, "getItem");

let count = 0;
let skipCount = 0; // 设置你想跳过的打印次数
// 你可以定义一个数组，用来存放你想要忽略的属性名
let ignoreList = [
  "document",
  "navigator",
  "location",
  "localStorage",
  "sessionStorage",
  "screen",
  "histroy",
];

function proxy(obj, objName) {
  let printedProps = new Set(); // 用 Set 来保存已经打印过的属性名,过滤掉重复属性
  let handler = {
    get(target, prop, receiver) {
      // 你可以检查 prop 是否在忽略列表中，如果是，就直接返回原始值，不进行拦截
      if (ignoreList.includes(prop)) {
        return Reflect.get(target, prop, receiver);
      }
      // 其他部分不变
      if (!printedProps.has(prop)) {
        let result = Reflect.get(target, prop, receiver);
        count++;
        if (typeof result === "function") {
          if (result.toString().length <= 60) {
            // 检查是否跳过打印
            if (skipCount > 0) {
              skipCount--;
            } else {
              debugLog(
                "计数:",
                count,
                "[" + objName + "]",
                "获取属性",
                prop,
                "   [FF函数经过]=>",
                result.toString()
              );
            }
          } else {
            // 检查是否跳过打印
            if (skipCount > 0) {
              skipCount--;
            } else {
              debugLog(
                "计数:",
                count,
                "[" + objName + "]",
                "获取属性(===toString值太长===):",
                prop
              );
            }
          }
          result = proxy(result, objName + "." + prop); // 对函数属性进行递归代理
        } else if (
          typeof result === "object" &&
          result !== null &&
          result !== undefined
        ) {
          if (result.toString().length <= 60) {
            // 检查是否跳过打印
            if (skipCount > 0) {
              skipCount--;
            } else {
              debugLog(
                "计数:",
                count,
                "[" + objName + "]",
                "获取属性",
                prop,
                "   [OO对象经过]=>",
                result.toString()
              );
            }
          } else {
            // 检查是否跳过打印
            if (skipCount > 0) {
              skipCount--;
            } else {
              debugLog(
                "计数:",
                count,
                "[" + objName + "]",
                "获取属性(===toString值太长===):",
                prop
              );
            }
          }
          result = proxy(result, objName + "." + prop); // 对对象属性进行递归代理
        } else {
          // 检查是否跳过打印
          if (skipCount > 0) {
            skipCount--;
          } else {
            debugLog(
              "计数:",
              count,
              "[" + objName + "]",
              "获取属性",
              prop,
              "   [值为]=>",
              result
            );
          }
        }
        printedProps.add(prop); // 记录已经打印过的属性
        return result;
      }
      return Reflect.get(target, prop, receiver);
    },
    set(target, propKey, value, receiver) {
      // 同样，你可以检查 propKey 是否在忽略列表中，如果是，就直接返回原始值，不进行拦截
      if (ignoreList.includes(propKey)) {
        return Reflect.set(target, propKey, value, receiver);
      }
      // 其他部分不变
      if (!printedProps.has(propKey)) {
        count++;
        if (typeof value === "function") {
          if (value.toString().length <= 60) {
            // 检查是否跳过打印
            if (skipCount > 0) {
              skipCount--;
            } else {
              debugLog(
                "计数:",
                count,
                "[" + objName + "]",
                "  设置属性:",
                propKey,
                "   value:   ",
                value.toString()
              );
            }
          } else {
            // 检查是否跳过打印
            if (skipCount > 0) {
              skipCount--;
            } else {
              debugLog(
                "计数:",
                count,
                "[" + objName + "]",
                "  设置属性(===toString值太长===):",
                propKey
              );
            }
          }
        } else {
          // 检查是否跳过打印
          if (skipCount > 0) {
            skipCount--;
          } else {
            debugLog(
              "计数:",
              count,
              "[" + objName + "]",
              "  设置属性:",
              propKey,
              "   value:   ",
              value
            );
          }
        }
        printedProps.add(propKey); // 记录已经打印过的属性
      }
      return Reflect.set(target, propKey, value, receiver);
    },
  };
  return new Proxy(obj, handler);
}

/////=========构造函数============
Window = function Window() {};
ffglobal.reNameObj(Window, "Window");

Document = function Document() {};
ffglobal.reNameObj(Document, "Document");
HTMLDocument = function HTMLDocument() {};
ffglobal.reNameObj(HTMLDocument, "HTMLDocument");
Location = function Location() {};
ffglobal.reNameObj(Location, "Location");
History = function History() {};
ffglobal.reNameObj(History, "History");
Navigator = function Navigator() {};

ffglobal.reNameObj(Navigator, "Navigator");
Screen = function Screen() {};
ffglobal.reNameObj(Screen, "Screen");
Storage = function Storage() {};
ffglobal.reNameObj(Storage, "Storage");
////================原型绑定================///////
window.__proto__ = Window.prototype;
document.__proto__ = HTMLDocument.prototype;
HTMLDocument.prototype.__proto__ = Document.prototype;
location.__proto__ = Location.prototype;
history.__proto__ = History.prototype;
navigator.__proto__ = Navigator.prototype;
screen.__proto__ = Screen.prototype;
localStorage.__proto__ = Storage.prototype;
sessionStorage.__proto__ = Storage.prototype;
/////===================代理对象=====================//////
window = proxy(window, "window");
document = proxy(document, "document");
navigator = proxy(navigator, "navigator");
location = proxy(location, "location");
history = proxy(history, "history");
screen = proxy(screen, "screen");
localStorage = proxy(localStorage, "localStorage");
sessionStorage = proxy(sessionStorage, "sessionStorage");
_canvas = proxy(_canvas, "_canvas");
all = proxy(document.all, "_all");
documentElement = proxy(document.documentElement, "_documentElement");
_span = proxy(_span, "_span");
/////==========代码==================
/* V 1.0.1.19-fix.01 */
require("./bdms.js");

function get_abgous(url) {
  var t = {
    aid: 6383,
    pageId: 6241,
    paths: [
      "^/webcast/",
      "^/aweme/v1/",
      "^/aweme/v2/",
      "/v1/message/send",
      "^/live/",
      "^/captcha/",
      "^/ecom/",
    ],
    boe: false,
    ddrt: 8.5,
    ic: 8.5,
  };
  window.bdms.init(t);
  xhr = new XMLHttpRequest();
  xhr.bdmsInvokeList = [
    {
      args: ["GET", url, true],
    },
    {
      args: ["Accept", "application/json, text/plain, */*"],
    },
    {
      args: [
        "uifid",
        "163eead721bc91ca6f3a3cb4766a73c0638fabced1012e02c28bcbf3169aca5cb1348391d76f63e2f9da4d719c4da32217a9b2949c98efebcf51e3c9c7e1d0966c784065b26bf6b319b04de558d7cb318383c29fa3a83356e1edcec69ee2d2b9c261a4ab36ad07403666f4f2b321382d22bc25bc620e23bcf48eaac8ccce297a7305d63b5b82ddf5a8eb9dc5afb305639b5d8324a5feb6a13e74d04fbdcf11b6",
      ],
    },
  ];
  xhr.invokeList = [
    {
      name: "addEventListener",
      args: ["load", null],
    },
    {
      name: "addEventListener",
      args: ["error", null],
    },
  ];
  xhr._vc_status = 1;
  xhr.send(null);
  process = process_;
  debugLog("window.a_bogus =>", window.a_bogus);
  return window.a_bogus;
}

get_abgous();
